﻿/* 
This file is part of Ingo Karstein's SharePoint PowerShell Timer Jobs project

**Do not remove this comment**

Please see the project homepage at CodePlex:
  http://sppowershelltimerjob.codeplex.com/

Please see my blog:
  http://ikarstein.wordpress.com

Licence: GPLv2
    Ingo Karstein's SharePoint PowerShell Timer Jobs
    Copyright (C) 2011  Ingo Karstein, ikarstein@hotmail.com

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation.Host;
using System.Management.Automation;
using System.Security;
using System.Globalization;

namespace ik.SharePoint2010.SPPowerShellTimerJob
{
    internal class PSHostRawUI : PSHostRawUserInterface
    {

        public override ConsoleColor BackgroundColor
        {
            get; set;
        }

        private Size _bufferSize = new Size(int.MaxValue, int.MaxValue);

        public override Size BufferSize
        {
            get
            {
                return _bufferSize;
            }
            set
            {
                _bufferSize = value;
            }
        }

        private Coordinates _cursorPosition = new Coordinates(0,0);

        public override Coordinates CursorPosition
        {
            get
            {
                return _cursorPosition; 
            }
            set
            {
                _cursorPosition = value;
            }
        }

        public override int CursorSize
        {
            get
            {
                return 8;
            }
            set
            {
            }
        }

        public override void FlushInputBuffer()
        {
            throw new Exception("Not implemented: ik.PowerShell.PSHostRawUI.FlushInputBuffer");
        }

        public override ConsoleColor ForegroundColor
        {
            get;
            set;
        }

        public override BufferCell[,] GetBufferContents(Rectangle rectangle)
        {
            throw new Exception("Not implemented: ik.PowerShell.PSHostRawUI.GetBufferContents");
        }

        public override bool KeyAvailable
        {
            get
            {
                throw new Exception("Not implemented: ik.PowerShell.PSHostRawUI.KeyAvailable/Get");
            }
        }

        public override Size MaxPhysicalWindowSize
        {
            get
            {
                return new Size(int.MaxValue,int.MaxValue);
            }
        }

        public override Size MaxWindowSize
        {
            get
            {
                return new Size(int.MaxValue, int.MaxValue);
            }
        }

        public override KeyInfo ReadKey(ReadKeyOptions options)
        {
            throw new Exception("Not implemented: ik.PowerShell.PSHostRawUI.ReadKey");
        }

        public override void ScrollBufferContents(Rectangle source, Coordinates destination, Rectangle clip, BufferCell fill)
        {
            throw new Exception("Not implemented: ik.PowerShell.PSHostRawUI.ScrollBufferContents");
        }

        public override void SetBufferContents(Rectangle rectangle, BufferCell fill)
        {
            throw new Exception("Not implemented: ik.PowerShell.PSHostRawUI.SetBufferContents(1)");
        }

        public override void SetBufferContents(Coordinates origin, BufferCell[,] contents)
        {
            throw new Exception("Not implemented: ik.PowerShell.PSHostRawUI.SetBufferContents(2)");
        }

        public override Coordinates WindowPosition
        {
            get
            {
                return new Coordinates(0, 0);
            }
            set
            {
            }
        }

        public override Size WindowSize
        {
            get
            {
                return new Size(int.MaxValue, int.MaxValue);
            }
            set
            {
            }
        }

        public override string WindowTitle
        {
            get
            {
                return "PowerShell Timer Job";
            }
            set
            {
            }
        }
    }
    internal class PSHostUI : PSHostUserInterface
    {
        private PSHostRawUI rawUI = null;
        private IPSApp parentApp;

        public PSHostUI()
            : base()
        {
            rawUI = new PSHostRawUI();
        }

        public IPSApp ParentApp
        {
            set
            {
                parentApp = value;
            }
        }

        public override Dictionary<string, PSObject> Prompt(string caption, string message, System.Collections.ObjectModel.Collection<FieldDescription> descriptions)
        {
            throw new NotImplementedException("User interaction is not supported in PowerShell Timer Job scripts!");
        }

        public override int PromptForChoice(string caption, string message, System.Collections.ObjectModel.Collection<ChoiceDescription> choices, int defaultChoice)
        {
            throw new NotImplementedException("User interaction is not supported in PowerShell Timer Job scripts!");
        }

        public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName, PSCredentialTypes allowedCredentialTypes, PSCredentialUIOptions options)
        {
            throw new NotImplementedException("Prompting for user credentials is not supported in PowerShell Timer Job scripts!");
        }

        public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName)
        {
            throw new NotImplementedException("Prompting for user credentials is not supported in PowerShell Timer Job scripts!");
        }

        public override PSHostRawUserInterface RawUI
        {
            get
            {
                return rawUI;
            }
        }

        public override string ReadLine()
        {
            throw new NotImplementedException("User interaction is not supported in PowerShell Timer Job scripts!");
        }

        public override System.Security.SecureString ReadLineAsSecureString()
        {
            throw new NotImplementedException("User interaction is not supported in PowerShell Timer Job scripts!");
        }

        public override void Write(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value)
        {
            parentApp.Write( value);
        }

        public override void Write(string value)
        {
            parentApp.Write(value);
        }

        public override void WriteDebugLine(string message)
        {
            parentApp.WriteLine("DEBUG: " + message);
        }

        public override void WriteErrorLine(string value)
        {
            parentApp.WriteLine("ERROR: " + value);
        }

        public override void WriteLine(string value)
        {
            parentApp.WriteLine( value);
        }

        public override void WriteProgress(long sourceId, ProgressRecord record)
        {
            parentApp.WriteLine("PROGRESS: " + string.Format("{0}", record.CurrentOperation));
        }

        public override void WriteVerboseLine(string message)
        {
            parentApp.WriteLine("VERBOSE: " + message);
        }

        public override void WriteWarningLine(string message)
        {
            parentApp.WriteLine("WARNING: " + message);
        }

        public override void WriteLine()
        {
            parentApp.WriteLine("");
        }
        public override void WriteLine(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value)
        {
            parentApp.WriteLine(value);
        }
    }



    internal class PS2EXEHost : PSHost
    {
        private IPSApp parent;
        private PSHostUI ui = null;

        private CultureInfo originalCultureInfo =
            System.Threading.Thread.CurrentThread.CurrentCulture;

        private CultureInfo originalUICultureInfo =
            System.Threading.Thread.CurrentThread.CurrentUICulture;

        private Guid myId = Guid.NewGuid();

        public PS2EXEHost(IPSApp app, PSHostUI ui)
        {
            this.parent = app;
            this.ui = ui;
        }

        public override System.Globalization.CultureInfo CurrentCulture
        {
            get
            {
                return this.originalCultureInfo;
            }
        }

        public override System.Globalization.CultureInfo CurrentUICulture
        {
            get
            {
                return this.originalUICultureInfo;
            }
        }

        public override Guid InstanceId
        {
            get
            {
                return this.myId;
            }
        }

        public override string Name
        {
            get
            {
                return "PowerShellTimerJobHost";
            }
        }

        public override PSHostUserInterface UI
        {
            get
            {
                return ui;  
            }
        }

        public override Version Version
        {
            get
            {
                return new Version(1, 0, 0, 0);
            }
        }

        public override void EnterNestedPrompt()
        {
        }

        public override void ExitNestedPrompt()
        {
        }

        public override void NotifyBeginApplication()
        {
            return;
        }

        public override void NotifyEndApplication()
        {
            return;
        }

        public override void SetShouldExit(int exitCode)
        {
            this.parent.ShouldExit = true;
            this.parent.ExitCode = exitCode;
        }
    }



    internal interface IPSApp
    {
        bool ShouldExit
        {
            get;
            set;
        }
        int ExitCode
        {
            get;
            set;
        }

        void Write(string s);
        void WriteLine(string s);
    }
}
